package com.smday.recursion;

/**
 * @author Summerday
 */
public class Queen8 {

    //定义max表示共有多少个皇后
    private int max = 8;

    //定义数组array,保存皇后放置的结果
    private int[] array = new int[max];

    //记录解法数
    static int count = 0;
    //记录判断冲突数
    static int judgeCount = 0;

    public static void main(String[] args) {

        Queen8 queen8 = new Queen8();
        queen8.check(0);

        System.out.printf("共计解法: %d\n", count);
        System.out.printf("共计判断: %d\n", judgeCount);

    }

    //放置第n个皇后,每次进入递归进入check都有for(int i = 0;i<max;i++),回溯
    private void check(int n){

        if(n == max){
            print();

            return;
        }
        //依次放入皇后,并判断是否为空
        for(int i = 0;i<max;i++){

            
            //先把当前皇后n放到该行的第1列
            array[n] = i;

            //判断当放置第n个皇后到i列时,是否冲突

            if(judge(n)){
                //不冲突,接着放n+1个皇后
                check(n+1);

            }
            //如果冲突,会继续执行array[n] = i; 此时i已经+1
        }

    }

    //查看当我们放置第n个皇后时,就检测该皇后是否和前面已经摆放的皇后冲突

    private boolean judge(int n){
        judgeCount++;
        for(int i = 0;i<n;i++){
            //array[i] == array[n] 代表在同一列

            //Math.abs(array[i]-array[n]) == Math.abs(i-n) 代表在同一斜线

            //n本身代表行数,不可能同一行
            if(array[i] == array[n]||Math.abs(array[i]-array[n]) == Math.abs(i-n)){
                return false;
            }
        }
        return true;
    }



    //将皇后摆放的位置输出
    private void print(){
        count++;
        for (int i : array) {
            System.out.print(i+" ");
        }
        System.out.println();
    }
}



